package com.itheima.controller;

import com.itheima.pojo.Dept;
import com.itheima.pojo.Result;
import com.itheima.service.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author zhouchichen
 * @since 2025/7/19
 */
@Slf4j
@RestController
@RequestMapping("/depts")
public class DeptController {
    // private static final Logger log = LoggerFactory.getLogger(DeptController.class);

    @Resource
    private DeptService deptService;

    /**
     * 一、Controller里的方法，需要设置：
     *  资源路径：客户端必须通过此路径才能访问到这个方法
     *  请求方式：客户端必须使用此请求方式才能访问到这个方法
     * 具体实现：利用@RequestMapping的衍生注解
     *  1.只允许GET请求访问：@GetMapping("资源路径")
     *  2.只允许POST请求访问：@PostMapping("资源路径")
     *  3.只允许PUT请求访问：@PutMapping("资源路径")
     *  4.只允许DELETE请求访问：@DeleteMapping("资源路径")
     * 二、Controller里所有方法的返回值，统一使用Result对象
     *  原因：如果没有统一的返回值，就会导致 每个方法返回的结果都不一样，乱
     *      后端代码返回值太乱，不规范
     *      前端收到响应结果，每个功能收到的返回值都不同，要有不同的处理
     *  做法：所有方法返回值必须要有一个统一的规范(每个项目组有自己的规范，进公司以后看别人写的代码，别人的Controller返回什么，自己也返回什么)
     *      我们的tlias项目要求返回统一的Result对象
     *      如果成功了：
     *          如果不需要返回结果数据：return Result.success()
     *          如果需要返回结果数据：return Result.success(要响应的数据)
     *      如果失败了：
     *          return Result.error("失败描述")
     */
    @GetMapping
    public Result queryAll(){
        // log.debug("debug级别的日志--queryAll方法执行了");
        // log.info("info级别的日志--queryAll方法执行了");
        // log.warn("warn级别的日志--queryAll方法执行了");
        // log.error("error级别的日志--queryAll方法执行了");
        log.info("查询所有部门");

        // 调用service完成功能，得到结果数据
        List<Dept> deptList = deptService.queryAll();
        // 将结果数据封装成Result对象并返回
        return Result.success(deptList);
    }

    /**
     * Controller里如何接收表单格式的参数：
     *  表单格式的参数是什么样的？参数名=值&参数名=值&...
     *  接收表单格式的参数，方式：
     *      1. 给Controller增加形参，一个形参用于接收一个表单参数。参数类型 可以由框架自动转换
     *      2. 给形参上加增加@RequestParam("表单参数名")
     *         如果方法形参名 与 表单参数名相同，可以省略@RequestParam 可不写
     */
    @DeleteMapping
    public Result deleteById(Integer id){
        log.info("根据id删除部门，id={}", id);
        deptService.deleteById(id);
        return Result.success();
    }

    /**
     * Controller里如何接收json格式的参数：
     *  json格式的参数是什么样的？
     *      对象形式：{"参数名": 值, "参数名", 值,...}
     *      数组形式：[ 值1, 值2,... ]  其中每个值可能是数字、字符串、boolean，也可以是json对象、json数组
     *  Controller里该如何接收json参数：
     *      1. 只能整体接收json的所有数据，不能只接收其中的一部分参数
     *      2. 通常是接收成JavaBean对象(或者集合)：给方法增加JavaBean类型的形参(或者集合类型的形参)
     *         json里有什么样的参数名，JavaBean里就必须有同名的属性
     *      3. 为方法形参增加注解：@RequestBody
     */
    @PostMapping
    public Result add(@RequestBody Dept dept){
        log.info("新增部门，dept={}", dept);
        deptService.add(dept);
        return Result.success();
    }

    /**
     * Controller里如何接收路径参数？
     *  路径参数是什么样的？在请求路径里携带的参数值，比如： GET /depts/1  这里的1就是客户端提交的参数值
     *  Controller里怎么接收路径参数：
     *      1. 给方法增加形参，一个形参可以对应一个路径参数
     *      2. 给方法设置路径标识时，需要添加表达式，用表达式对应路径参数。@GetMapping("/depts/{xxx}")
     *          其中{xx}表示一个占位符，用于匹配实际请求路径里的路径参数
     *      3. 给方法形参增加注解@PathVariable("占位符名称")
     *      注意：如果占位符名称 和 方法形参名相同，可以简写成 @PathVariable
     */
    @GetMapping("/{id}")
    public Result findById(@PathVariable Integer id){
        log.info("根据id查询部门，id={}", id);
        Dept dept = deptService.findById(id);
        return Result.success(dept);
    }

    @PutMapping
    public Result update(@RequestBody Dept dept){
        log.info("修改部门，dept={}", dept);
        deptService.updateById(dept);
        return Result.success();
    }
}
